// Base64 Encoding (Base64编码) 示例
// 演示 Pascal 中Base64编码的各种用法
program p_50_base64_encoding;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,        // 系统工具单元
  Classes,         // 类单元
  EncdDecd;        // 编码解码单元

// 字符串的Base64编码和解码示例
procedure StringBase64EncodingAndDecoding;
var
  originalText: String;
  encodedText: String;
  decodedText: String;
begin
  WriteLn('1. 字符串的Base64编码和解码:');
  
  // 基本字符串编码
  originalText := 'Hello, Pascal World!';
  WriteLn('  原始文本: "', originalText, '"');
  
  encodedText := EncodeStringBase64(originalText);
  WriteLn('  Base64编码: "', encodedText, '"');
  
  decodedText := DecodeStringBase64(encodedText);
  WriteLn('  解码结果: "', decodedText, '"');
  
  WriteLn;
  
  // 中文字符串编码
  originalText := '你好，Pascal编程世界！';
  WriteLn('  中文原始文本: "', originalText, '"');
  
  encodedText := EncodeStringBase64(originalText);
  WriteLn('  Base64编码: "', encodedText, '"');
  
  decodedText := DecodeStringBase64(encodedText);
  WriteLn('  解码结果: "', decodedText, '"');
  
  WriteLn;
  
  // 特殊字符编码
  originalText := '用户名:admin@123, 密码:pa$$w0rd!';
  WriteLn('  特殊字符文本: "', originalText, '"');
  
  encodedText := EncodeStringBase64(originalText);
  WriteLn('  Base64编码: "', encodedText, '"');
  
  decodedText := DecodeStringBase64(encodedText);
  WriteLn('  解码结果: "', decodedText, '"');
end;

// 二进制数据的Base64编码和解码示例
procedure BinaryDataBase64EncodingAndDecoding;
var
  originalData: TBytes;
  encodedData: String;
  decodedData: TBytes;
  i: Integer;
begin
  WriteLn('2. 二进制数据的Base64编码和解码:');
  
  // 创建示例二进制数据
  SetLength(originalData, 10);
  for i := 0 to 9 do
    originalData[i] := Byte(i * 10);
  
  Write('  原始二进制数据: ');
  for i := 0 to High(originalData) do
    Write(originalData[i]:3);
  WriteLn;
  
  // 编码二进制数据
  encodedData := EncodeBase64(@originalData[0], Length(originalData));
  WriteLn('  Base64编码: "', encodedData, '"');
  
  // 解码二进制数据
  SetLength(decodedData, Length(originalData));
  var decodedLength := DecodeBase64(encodedData, @decodedData[0]);
  Write('  解码二进制数据: ');
  for i := 0 to decodedLength - 1 do
    Write(decodedData[i]:3);
  WriteLn;
  
  // 验证数据一致性
  var isMatch := True;
  if decodedLength = Length(originalData) then
  begin
    for i := 0 to decodedLength - 1 do
    begin
      if decodedData[i] <> originalData[i] then
      begin
        isMatch := False;
        Break;
      end;
    end;
  end
  else
    isMatch := False;
  
  WriteLn('  数据一致性检查: ', BoolToStr(isMatch, True));
end;

// 文件内容的Base64编码示例
procedure FileContentBase64Encoding;
var
  stringStream: TStringStream;
  fileContent: String;
  encodedContent: String;
begin
  WriteLn('3. 文件内容的Base64编码:');
  
  // 模拟文件内容
  fileContent := '这是一些示例文件内容。' + LineEnding +
                 '它包含多行文本。' + LineEnding +
                 '可以用于演示Base64编码。' + LineEnding +
                 '文件ID: 12345' + LineEnding +
                 '创建时间: ' + DateTimeToStr(Now);
  
  WriteLn('  原始文件内容:');
  var lines := fileContent.Split([LineEnding]);
  for var i := 0 to High(lines) do
    WriteLn('    ', lines[i]);
  
  // 编码文件内容
  encodedContent := EncodeStringBase64(fileContent);
  WriteLn('  Base64编码结果:');
  WriteLn('    ', encodedContent);
  
  // 解码验证
  var decodedContent := DecodeStringBase64(encodedContent);
  WriteLn('  解码验证结果:');
  lines := decodedContent.Split([LineEnding]);
  for var i := 0 to High(lines) do
    WriteLn('    ', lines[i]);
  
  var isMatch := (fileContent = decodedContent);
  WriteLn('  内容一致性检查: ', BoolToStr(isMatch, True));
end;

// URL安全的Base64编码示例
procedure URLSafeBase64Encoding;
var
  originalText: String;
  standardEncoded: String;
  urlSafeEncoded: String;
  standardDecoded: String;
  urlSafeDecoded: String;
begin
  WriteLn('4. URL安全的Base64编码:');
  
  originalText := '用户参数: id=123&name=张三&role=admin';
  WriteLn('  原始文本: "', originalText, '"');
  
  // 标准Base64编码
  standardEncoded := EncodeStringBase64(originalText);
  WriteLn('  标准Base64编码: "', standardEncoded, '"');
  
  // URL安全的Base64编码（手动替换）
  urlSafeEncoded := standardEncoded;
  urlSafeEncoded := StringReplace(urlSafeEncoded, '+', '-', [rfReplaceAll]);
  urlSafeEncoded := StringReplace(urlSafeEncoded, '/', '_', [rfReplaceAll]);
  urlSafeEncoded := StringReplace(urlSafeEncoded, '=', '', [rfReplaceAll]);
  WriteLn('  URL安全Base64编码: "', urlSafeEncoded, '"');
  
  // 解码标准Base64
  standardDecoded := DecodeStringBase64(standardEncoded);
  WriteLn('  标准Base64解码: "', standardDecoded, '"');
  
  // 解码URL安全Base64（恢复后再解码）
  var restored := urlSafeEncoded;
  // 补充可能丢失的填充字符
  var padding := Length(restored) mod 4;
  if padding > 0 then
    restored := restored + StringOfChar('=', 4 - padding);
  restored := StringReplace(restored, '-', '+', [rfReplaceAll]);
  restored := StringReplace(restored, '_', '/', [rfReplaceAll]);
  urlSafeDecoded := DecodeStringBase64(restored);
  WriteLn('  URL安全Base64解码: "', urlSafeDecoded, '"');
  
  var isMatch := (originalText = standardDecoded) and (originalText = urlSafeDecoded);
  WriteLn('  解码一致性检查: ', BoolToStr(isMatch, True));
end;

// Base64编码在实际应用中的使用示例
procedure PracticalBase64Applications;
var
  // 模拟用户数据
  userData: String;
  encodedCredentials: String;
  // 模拟图片数据
  imageData: String;
  encodedImage: String;
  // 模拟配置数据
  configData: String;
  encodedConfig: String;
begin
  WriteLn('5. Base64编码在实际应用中的使用:');
  
  // 用户认证信息编码
  WriteLn('  用户认证信息编码:');
  userData := 'username=admin&password=secret123';
  WriteLn('    原始认证数据: "', userData, '"');
  
  encodedCredentials := EncodeStringBase64(userData);
  WriteLn('    Base64编码: "', encodedCredentials, '"');
  
  var decodedCredentials := DecodeStringBase64(encodedCredentials);
  WriteLn('    解码验证: "', decodedCredentials, '"');
  
  WriteLn;
  
  // 图片数据编码（模拟）
  WriteLn('  图片数据编码:');
  imageData := 'PNG图片数据模拟内容...';
  WriteLn('    原始图片数据: "', imageData, '"');
  
  encodedImage := EncodeStringBase64(imageData);
  WriteLn('    Base64编码: "', encodedImage, '"');
  
  var decodedImage := DecodeStringBase64(encodedImage);
  WriteLn('    解码验证: "', decodedImage, '"');
  
  WriteLn;
  
  // 配置数据编码
  WriteLn('  配置数据编码:');
  configData := '{"server":"localhost","port":8080,"debug":true,"timeout":30}';
  WriteLn('    原始配置数据: "', configData, '"');
  
  encodedConfig := EncodeStringBase64(configData);
  WriteLn('    Base64编码: "', encodedConfig, '"');
  
  var decodedConfig := DecodeStringBase64(encodedConfig);
  WriteLn('    解码验证: "', decodedConfig, '"');
  
  WriteLn;
  
  // 组合使用示例
  WriteLn('  组合使用示例:');
  var combinedData := '认证信息:' + encodedCredentials + ';配置信息:' + encodedConfig;
  WriteLn('    组合数据: "', combinedData, '"');
end;

// Base64编码的性能考虑示例
procedure Base64PerformanceConsiderations;
var
  testData: String;
  encodedData: String;
  startTime, endTime: QWord;
  i: Integer;
begin
  WriteLn('6. Base64编码的性能考虑:');
  
  // 生成测试数据
  testData := '';
  for i := 1 to 1000 do
    testData := testData + '这是第' + IntToStr(i) + '行测试数据。' + LineEnding;
  
  WriteLn('  测试数据大小: ', Length(testData), ' 字符');
  
  // 测试编码性能
  startTime := GetTickCount64;
  for i := 1 to 100 do  // 重复100次
    encodedData := EncodeStringBase64(testData);
  endTime := GetTickCount64;
  
  WriteLn('  编码耗时: ', (endTime - startTime), ' 毫秒 (100次)');
  WriteLn('  平均每次编码耗时: ', ((endTime - startTime) / 100):0:2, ' 毫秒');
  WriteLn('  编码后数据大小: ', Length(encodedData), ' 字符');
  WriteLn('  数据膨胀率: ', (Length(encodedData) / Length(testData) * 100):0:1, '%');
  
  // 测试解码性能
  startTime := GetTickCount64;
  for i := 1 to 100 do  // 重复100次
    var decodedData := DecodeStringBase64(encodedData);
  endTime := GetTickCount64;
  
  WriteLn('  解码耗时: ', (endTime - startTime), ' 毫秒 (100次)');
  WriteLn('  平均每次解码耗时: ', ((endTime - startTime) / 100):0:2, ' 毫秒');
  
  WriteLn;
  WriteLn('  性能提示:');
  WriteLn('    - Base64编码会使数据大小增加约33%');
  WriteLn('    - 对于大文件，考虑分块处理');
  WriteLn('    - 避免在循环中频繁编码/解码');
  WriteLn('    - 在内存敏感的应用中注意数据复制');
end;

// 程序主入口
begin
  WriteLn('=== Pascal Base64编码示例 ===');
  WriteLn;
  
  // 1. 字符串的Base64编码和解码
  StringBase64EncodingAndDecoding;
  
  WriteLn;
  
  // 2. 二进制数据的Base64编码和解码
  BinaryDataBase64EncodingAndDecoding;
  
  WriteLn;
  
  // 3. 文件内容的Base64编码
  FileContentBase64Encoding;
  
  WriteLn;
  
  // 4. URL安全的Base64编码
  URLSafeBase64Encoding;
  
  WriteLn;
  
  // 5. Base64编码在实际应用中的使用
  PracticalBase64Applications;
  
  WriteLn;
  
  // 6. Base64编码的性能考虑
  Base64PerformanceConsiderations;
  
  WriteLn;
  WriteLn('演示了 Pascal 中Base64编码的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.